package com.conan.dailyflickr.app;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.json.JSONException;
import org.json.JSONObject;

import android.net.Uri;
import android.util.Log;

import com.conan.dailyflickr.app.PhotoDailyInfo.Photo;
import com.conan.dailyflickr.app.PhotoDailyInfo.PhotoSize;

public class FlickrApiHelper {
	
	private static final String API_REST_HOST = "api.flickr.com";
    private static final String API_REST_URL = "/services/rest/";
    // private static final String API_FEED_URL = "/services/feeds/photos_public.gne";
    private static final String API_DAILY_INTERRESTING = "flickr.interestingness.getList";
    

    private static final String PARAM_API_KEY = "api_key";
    private static final String PARAM_METHOD= "method";
    private static final String PARAM_PAGE= "page";
    private static final String PARAM_DATE= "date";
    private static final String PARAM_PER_PAGE = "per_page";
    private static final String PARAM_EXTRA = "extras";
    private static final String PARAM_EXTRA_DATE_TAKEN = "date_taken";
    
    // private static final String PHOTO_IMAGE_URL = "http://farm%s.static.flickr.com/%s/%s_%s%s.jpg";
	
	private static final int IO_BUFFER_SIZE = 4*1024;
	    
	private static FlickrApiHelper instance = new FlickrApiHelper();
	
	
    public final static FlickrApiHelper getInstance() {
        return instance;
    }

	public FlickrApiHelper() {
		final HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, "UTF-8");

		final SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

		final ThreadSafeClientConnManager manager =
			new ThreadSafeClientConnManager(params, registry);

		mClient = new DefaultHttpClient(manager, params);

	}
	private static final String API_KEY = "730e3a4f253b30adf30177df803d38c4"; //38c4
	// "http://api.flickr.com/services/rest/
	// ?method=flickr.interestingness.getList
	// &api_key=5e1b20ebc4dcca15de7a0b660daac613
	// &format=rest
	// &api_sig=ddbfe471175cd28bd9f519e5336243ed --> no need add url
	// page=
	public Uri.Builder buildGetURI(){
		final Uri.Builder builder = new Uri.Builder();
		builder.path(API_REST_HOST);
        builder.appendPath(API_REST_URL);        
        return builder;
	}
	
	private Uri.Builder buildGetQuery(String method){
		final Uri.Builder builder = new Uri.Builder();
		builder.path(API_REST_URL);
		builder.appendQueryParameter(PARAM_API_KEY, API_KEY);
        builder.appendQueryParameter("format", "json");
        builder.appendQueryParameter(PARAM_METHOD, method);
        return builder;
	}

	public Uri.Builder buildInterestingURI(){
		Uri.Builder builder = buildGetURI();
		builder.appendQueryParameter(PARAM_API_KEY, API_KEY);
        builder.appendQueryParameter("format", "json");
        builder.appendQueryParameter(PARAM_METHOD, API_DAILY_INTERRESTING);
		return builder;  
	}
	
	public Uri.Builder buildInterestingQuery(int page, int perpage, Date date){
		Uri.Builder builder = buildGetQuery(API_DAILY_INTERRESTING);		
		if(page == 0) page = 1;
		builder.appendQueryParameter(PARAM_PAGE, Integer.toString(page));
				
		// builder.appendQueryParameter(PARAM_PAGES, Integer.toString(pages));
		builder.appendQueryParameter(PARAM_PER_PAGE, Integer.toString(perpage));
		// date=2011-07-21
		// YYYY-MM-DD
		if( date != null){
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");		
			builder.appendQueryParameter(PARAM_DATE , formatter.format(date));
		}
		builder.appendQueryParameter(PARAM_EXTRA, PARAM_EXTRA_DATE_TAKEN);		
		
		return builder;  
	}
			 
	public JSONObject flickrPhotoApiHttp(int page, int perpage, Date date)throws IOException, JSONException {
		 final Uri.Builder uri = buildInterestingQuery(page, perpage, date);

	     final HttpGet get = new HttpGet(uri.build().toString());
	     JSONObject jSONObject = null;
	     
	     HttpEntity entity = executeRequestHttp(get);
	     if(entity == null) return null;
	     int size = (int)entity.getContentLength();
	     InputStream in = entity.getContent();
	     Log.d(PhotoDailyInfo.TAG, "flickrPhotoApiHttp = " + uri.build().toString());
    	 Log.d(PhotoDailyInfo.TAG, "[in.available()] = " + size);
    	 // String line = "";
         StringBuilder builder = new StringBuilder();
         BufferedReader reader = new BufferedReader(new InputStreamReader( in));
         // char[] line = new char[256];
         String line;
         while ((line = reader.readLine()) != null) {
         // while (reader.read(line) > 0) {
        	 Log.d(PhotoDailyInfo.TAG, line.toString());
        	 builder.append(line);
         }
         
         Log.d(PhotoDailyInfo.TAG, "content lenghth = " + builder.length());
         
         reader.close();
         entity.consumeContent();
         
         // Log.d("not good",builder.toString());
         //no, this is not yet a valid json response :)
  
         int start = builder.toString().indexOf("(") + 1;
         int end = builder.toString().length() - 1;
         String jSONString = builder.toString().substring( start, end);
         //after cutting off the junk, its ok
  
         //whole json object
		 jSONObject = new JSONObject(jSONString);

	     return jSONObject;
	}

	// source: flickr.com/services/api/misc.urls.html
	enum size {
	        _s /*75*/, _t /*100*/,_m /*240*/
	};
	   /**
     * Downloads the specified photo at the specified size in the specified destination.
     *
     * @param photo The photo to download.
     * @param size The size of the photo to download.
     * @param destination The output stream in which to write the downloaded photo.
     *
     * @throws IOException If any network exception occurs during the download.
     */
    public void downloadPhoto(Photo photo, PhotoSize size, OutputStream destination) throws IOException {
        final BufferedOutputStream out = new BufferedOutputStream(destination, IO_BUFFER_SIZE);
        final String url = photo.getUrl(size);
        final HttpGet get = new HttpGet(url);

        HttpEntity entity = null;
        try {
            final HttpResponse response = mClient.execute(get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                entity = response.getEntity();
                entity.writeTo(out);
                out.flush();
            }
        } finally {
            if (entity != null) {
                entity.consumeContent();
            }
        }
    }
    
	   /**
     * Executes an HTTP request on Flickr's web service. If the response is ok, the content
     * is sent to the specified response handler.
     *
     * @param get The GET request to executed.
     * @param handler The handler which will parse the response.
     * 
     * @throws IOException
     */
	
	private HttpClient mClient;
    public InputStream executeRequest(HttpGet get, ResponseHandler handler) throws IOException {
        HttpEntity entity = null;
        HttpHost host = new HttpHost(API_REST_HOST, 80, "http");
        InputStream in = null;
        try {
            final HttpResponse response = mClient.execute(host, get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                entity = response.getEntity();
                 /* final InputStream */in = entity.getContent();
//                handler.handleResponse(in);
            }
        } finally {
            if (entity != null) {
                entity.consumeContent();
            }
        }
        return in;
    }   
    
    private HttpEntity executeRequestHttp(HttpGet get) throws IOException {
        HttpEntity entity = null;
        HttpHost host = new HttpHost(API_REST_HOST, 80, "http");
        try {
            final HttpResponse response = mClient.execute(host, get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                entity = response.getEntity();
               
            }
        } catch (Exception e) {
        	if (entity != null) {
                entity.consumeContent();
            }
        }
        return entity;
    }   
}
